#include <iostream>
#include <cstring>
#include <algorithm>

namespace bit
{
    class string
    {
        friend std::ostream& operator<<(std::ostream& os, const string& s);
        friend std::istream& operator>>(std::istream& is, string& s);

    public:
        typedef char* iterator;
        static const size_t npos = -1;

        void swap(string& s)
        {
            std::swap(_str, s._str);
            std::swap(_size, s._size);
            std::swap(_capacity, s._capacity);
        }


        // 构造函数
        string(const char* str = "") : _size(strlen(str)) {
            _capacity = _size + 1;
            _str = new char[_capacity];
            strcpy(_str, str);
        }

        // 拷贝构造函数
        string(const string& s) : _size(s._size), _capacity(s._capacity) {
            _str = new char[_capacity+1];
            strcpy(_str, s._str);
        }

        // 赋值运算符
        string& operator=(const string& s) {
            // if (this != &s) {
            //     char* tmp = new char[s._capacity + 1];
            //     strcpy(tmp, s._str);
            //     delete[] _str;
            //     _str = tmp;
            //     _size = s._size;
            //     _capacity = s._capacity;
            // }
            if(this!=&s)
            {
                string tmp(s);
                swap(tmp); //tmp出作用域后析构，释放内存，避免手动释放原来的内存
            }
            return *this;
        }

        // 析构函数
        ~string() {
            delete[] _str;
            _str = nullptr;
            _size = _capacity = 0;
        }

        // 迭代器
        iterator begin() { return _str; }
        iterator end() { return _str + _size; }  //指向的是最后一个字符的下一个位置
        const iterator begin() const { return _str; }
        const iterator end() const { return _str + _size; } //const_iterator 用const修饰，不能修改内容

        // 修改操作

        void push_back(char c) {
            //先检查是否需要扩容
            if(_size + 1 > _capacity) {
                reserve((_capacity + 1) * 2); //扩容为原来的两倍
            }
            _str[_size] = c; //添加字符
            _size++; //增加字符串长度
            _str[_size] = '\0'; //添加结束符

        }

        string& operator+=(char c) {
            push_back(c);
            return *this;
        }

        void append(const char* str) {
            //追加字符串
            size_t len = strlen(str);
            if (_size + len > _capacity) {
                reserve(_size + len); //扩容
            }

            // for (size_t i = 0; i < len; ++i) {
            //     _str[_size + i] = str[i]; //添加字符
            // }
            strcpy(_str + _size, str); //直接使用strcpy函数添加字符
            _size += len; //增加字符串长度
        }

        string& operator+=(const char* str) {
            append(str);
            return *this;
        }

        void clear() {
            _size = 0;
            _str[0] = '\0';
        }


        
        const char* c_str() const { return _str; }

        // 容量操作
        size_t size() const { return _size; }
        size_t capacity() const { return _capacity; }
        bool empty() const { return _size == 0; }

        void resize(size_t n, char c = '\0') {
            if (n == _size) return; //大小相同，不需要修改
            if (n < _size) {  //小于当前大小，直接截断
                _size = n;
                _str[_size] = '\0';
            } 
            else if (n > _size) 
            {
                //大于会填充字符，默认是'\0'
                reserve(n);
                for (size_t i = _size; i < n; ++i) {
                    _str[i] = c;
                }
                _size = n;
                _str[_size] = '\0';
            }
        }

        void reserve(size_t n) {
            if (n > _capacity) {
                char* newStr = new char[n + 1]; //+1是为了添加结束符
                if (_str) {
                    strcpy(newStr, _str); //拷贝原来的字符串
                    delete[] _str; //释放原来的内存
                }
                _str = newStr; //指向新的内存
                _capacity = n; //更新容量
            }
        }

        // 访问操作符
        char& operator[](size_t index) { return _str[index]; }
        const char& operator[](size_t index) const { return _str[index]; }

        // 关系运算符
        bool operator<(const string& s) const { return strcmp(_str, s._str) < 0; }
        bool operator<=(const string& s) const { return strcmp(_str, s._str) <= 0; }
        bool operator>(const string& s) const { return strcmp(_str, s._str) > 0; }
        bool operator>=(const string& s) const { return strcmp(_str, s._str) >= 0; }
        bool operator==(const string& s) const { return strcmp(_str, s._str) == 0; }
        bool operator!=(const string& s) const { return !(*this == s); }

        // 查找
        size_t find(char c, size_t pos = 0) const {
            if (pos >= _size) return npos;
            const char* ptr = strchr(_str + pos, c);
            return ptr ? ptr - _str : npos;
        }

        size_t find(const char* s, size_t pos = 0) const {
            if (pos >= _size) return npos;
            const char* ptr = strstr(_str + pos, s);
            return ptr ? ptr - _str : npos;
        }

        // 插入
        string& insert(size_t pos, char c) {
            if (pos > _size) return *this;
            if (_size + 1 > _capacity) {
                reserve((_capacity + 1) * 2);
            }
            for (int i = _size; i > (int)pos; --i) {
                _str[i] = _str[i - 1];
            }
            _str[pos] = c;
            ++_size;
            _str[_size] = '\0';
            return *this;
        }

        string& insert(size_t pos, const char* str) {
            if (pos > _size) return *this;
            size_t len = strlen(str);
            if (len == 0) return *this;
            if (_size + len > _capacity) {
                reserve(_size + len);
            }
            // 使用int类型的循环变量，或者改变循环方式
            for (int i = _size; i >= (int)pos; --i) {  
                _str[i + len] = _str[i];
            }
            for (size_t i = 0; i < len; ++i) {
                _str[pos + i] = str[i];
            }
            _size += len;
            _str[_size] = '\0';  // 加结束符
            return *this;
        }

        
        // 删除
        string& erase(size_t pos, size_t len = npos) {
            if (pos >= _size) return *this;
            size_t maxLen = _size - pos;
            len = (len == npos || len > maxLen) ? maxLen : len;  //len的长度取决于pos和_size的差值
            if (len == 0) return *this;
            for (size_t i = pos; i <= _size - len; ++i) {
                _str[i] = _str[i + len];
            }
            _size -= len;
            _str[_size] = '\0';
            return *this;
        }

    private:
        char* _str = nullptr;
        size_t _capacity = 0;
        size_t _size = 0;
    };

    // 输出运算符
    std::ostream& operator<<(std::ostream& os, const string& s) {
        os << s.c_str();
        return os;
    }

    // 输入运算符
    std::istream& operator>>(std::istream& is, string& s) {
        s.clear();
        char c;
        while (is.get(c) && !isspace(c)) {
            s += c;
        }
        return is;
    }
}

// 测试代码
int main() {
    // 构造函数测试
    bit::string s1("Hello");
    std::cout << "s1: " << s1 << std::endl; // Hello

    // 拷贝构造
    bit::string s2(s1);
    std::cout << "s2: " << s2 << std::endl; // Hello

    // 赋值运算符
    bit::string s3;
    s3 = s1;
    std::cout << "s3: " << s3 << std::endl; // Hello

    // push_back
    s1.push_back('!');
    std::cout << "s1 after push_back: " << s1 << std::endl; // Hello!

    // operator+=
    s1 += '?';
    std::cout << "s1 after += char: " << s1 << std::endl; // Hello!?

    // append
    s1.append("World");
    std::cout << "s1 after append: " << s1 << std::endl; // Hello!?World

    // resize
    s1.resize(5);
    std::cout << "s1 after resize(5): " << s1 << std::endl; // Hello

    // 关系运算符
    bit::string s4("Apple"), s5("Banana");
    std::cout << "s4 < s5: " << (s4 < s5) << std::endl; // true

    // find
    size_t pos = s5.find('n');
    std::cout << "pos of 'n' in s5: " << pos << std::endl; // 3

    // insert
    s5.insert(0, "Big");
    std::cout << "s5 after insert: " << s5 << std::endl; // BigBanana

    // erase
    s5.erase(3, 3);
    std::cout << "s5 after erase: " << s5 << std::endl; // Biganana

    return 0;
}